﻿using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;

using RpcClient.Interface;

using RpcHelper;

namespace RpcClient.EventBus
{
    /// <summary>
    /// 本地事件
    /// </summary>
    internal class LocalEvent
    {
        /// <summary>
        /// 本地事件器
        /// </summary>
        private readonly ConcurrentDictionary<string, ILocalHandler> _Handlers = new ConcurrentDictionary<string, ILocalHandler>();
        /// <summary>
        /// 处理事件委托
        /// </summary>
        private event Action<object, string> _HandleEvent = null;
        /// <summary>
        /// 事件名称
        /// </summary>
        public string EventName
        {
            get;
        }
        public LocalEvent(string name)
        {
            this.EventName = name;
        }
        /// <summary>
        /// 发布事件
        /// </summary>
        /// <param name="arg">事件参数</param>
        public void Post(object arg)
        {
            if (_HandleEvent != null)
            {
                _ExecAction(arg);
            }
        }
        /// <summary>
        /// 异步发布事件
        /// </summary>
        /// <param name="arg">事件参数</param>
        public void AsyncPost(object arg)
        {
            if (_HandleEvent != null)
            {
                Task.Run(() =>
                {
                    _ExecAction(arg);
                });
            }
        }
        /// <summary>
        /// 执行委托队列
        /// </summary>
        /// <param name="arg"></param>
        private void _ExecAction(object arg)
        {
            try
            {
                _HandleEvent(arg, this.EventName);
            }
            catch (Exception e)
            {
                ErrorException error = ErrorException.FormatError(e);
                error.SaveLog(arg.ToJson(), "LocalEvent");
            }
        }
        /// <summary>
        /// 注册
        /// </summary>
        /// <param name="type"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public bool Reg(Type type, string name)
        {
            if (this._Handlers.ContainsKey(name))
            {
                return false;
            }
            ILocalHandler handler = new LocalEventHandler(type, name);
            if (this._Handlers.TryAdd(name, handler))
            {
                _HandleEvent += handler.HandleEvent;
                return true;
            }
            return false;
        }
        /// <summary>
        /// 移除
        /// </summary>
        /// <param name="name"></param>
        public void Remove(string name)
        {
            this._Handlers.TryRemove(name, out _);
        }
    }
}
